<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick, watch, computed } from 'vue'
import type { CommentVO, CommentAddReq, CommentQueryReq } from '@/types'
import { commentApi } from '@/api/comment'
import CommentReply from './CommentReply.vue'
import { useAuthStore } from '@/store/modules/auth'
import { SendPlane } from '@/components/icons'

const props = defineProps<{
  articleId: number
}>()

const comments = ref<CommentVO[]>([])
const loading = ref(false)
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const commentContent = ref('')

// 添加展开状态管理
const expandedComments = ref<Set<number>>(new Set())

// 添加新的响应式变量
const activeReplyId = ref<number | null>(null)
const replyComponents = ref<InstanceType<typeof CommentReply>[]>([])

// 添加观察器相关的变量
const loadingTrigger = ref<HTMLDivElement | null>(null)
let observer: IntersectionObserver | null = null

// 修改延迟时间
const LOADING_DELAY = 1000 // 1秒

// 添加是否已到底的状态
const isEnd = computed(() => comments.value.length >= total.value)

// 修改流函数
const throttle = (fn: Function, delay: number) => {
  let timer: NodeJS.Timeout | null = null
  let lastTime = 0
  return (...args: any[]) => {
    const now = Date.now()
    if (timer || loading.value || now - lastTime < delay) return

    // 只有在第二次滚动时才触发加载
    if (loadingTrigger.value?.dataset.shown === 'true') {
      loading.value = true
      lastTime = now
      timer = setTimeout(() => {
        fn(...args)
        timer = null
      }, delay)
    } else if (loadingTrigger.value) {
      loadingTrigger.value.dataset.shown = 'true'
    }
  }
}

// 切换展开状态
const toggleExpand = (commentId: number) => {
  console.log('toggleExpand triggered:', {
    commentId,
    isExpanded: expandedComments.value.has(commentId),
  })

  if (expandedComments.value.has(commentId)) {
    expandedComments.value.delete(commentId)
    if (activeReplyId.value === commentId) {
      activeReplyId.value = null
    }
  } else {
    expandedComments.value.add(commentId)
  }
  console.log('Expanded comments after toggle:', Array.from(expandedComments.value))
}

// 修改加载评论列表方法
const loadComments = async (page = 1) => {
  if (loading.value) return

  try {
    const params: CommentQueryReq = {
      pageIndex: page,
      pageSize: pageSize.value,
      topicId: props.articleId,
      parentId: 0,
      queryReply: false,
    }

    if (page > 1) {
      // 只有在加载更时才显示加载动画
      loading.value = true
      // 确保加载动画至少显示一定时间
      await new Promise((resolve) => setTimeout(resolve, LOADING_DELAY))
    }

    const response = await commentApi.pageQuery(params)
    if (response.data.code === 200) {
      const pageData = response.data.data
      const newComments = pageData.data
      comments.value = page === 1 ? newComments : [...comments.value, ...newComments]
      total.value = pageData.total
      currentPage.value = page
    }
  } catch (error) {
    console.error('加载评论失败:', error)
  } finally {
    loading.value = false
  }
}

// 提交评论
const submitComment = async () => {
  if (!commentContent.value.trim()) return

  try {
    const commentData: CommentAddReq = {
      topicId: props.articleId,
      commentContent: commentContent.value,
      parentId: 0,
      isReview: false,
    }
    const response = await commentApi.addComment(commentData)
    if (response.data.code === 200) {
      commentContent.value = ''
      await loadComments(1)
    }
  } catch (error) {
    console.error('提交评论失败:', error)
  }
}

// 修改创建观察器的方法
const createObserver = () => {
  if (typeof window === 'undefined') return

  observer?.disconnect()

  observer = new IntersectionObserver(
    (entries) => {
      if (
        entries[0].isIntersecting &&
        !loading.value &&
        comments.value.length < total.value &&
        entries[0].intersectionRatio > 0.5 // 增加可见度要求
      ) {
        const nextPage = currentPage.value + 1
        loadComments(nextPage)
      }
    },
    {
      root: null,
      rootMargin: '0px', // 减小预加载距离
      threshold: [0.5, 1.0], // 增加观察阈值
    },
  )

  if (loadingTrigger.value) {
    observer.observe(loadingTrigger.value)
  }
}

// 监听 loadingTrigger 的变化
watch(loadingTrigger, (el) => {
  if (el && observer) {
    observer.observe(el)
  }
})

// 修改处理回复输入框状态更新的方法
const handleReplyInputUpdate = (commentId: number, value: boolean) => {
  if (!value) {
    activeReplyId.value = null
  }
}

// 修改处理回复点击的方法
const handleReplyClick = (commentId: number) => {
  // 确保评论展开
  if (!expandedComments.value.has(commentId)) {
    expandedComments.value.add(commentId)
  }

  // 切换回复状态
  activeReplyId.value = activeReplyId.value === commentId ? null : commentId
}

// 添加处理回复提交的方法
const handleReplySubmitted = (commentId: number) => {
  activeReplyId.value = null
  // 更新评论列表中对应评论的回复数
  const comment = comments.value.find((c) => c.id === commentId)
  if (comment) {
    comment.replyCount++
  }
}

const textareaRef = ref<HTMLTextAreaElement | null>(null)

// 自动调整文本框高度
const autoResize = () => {
  if (textareaRef.value) {
    textareaRef.value.style.height = 'auto'
    const newHeight = Math.min(textareaRef.value.scrollHeight, 80) // 最大高度80px
    textareaRef.value.style.height = `${newHeight}px`
  }
}

// 监听评论内容变化
watch(commentContent, () => {
  nextTick(() => {
    autoResize()
  })
})

// 在 script setup 顶部添加 showCommentBox
const showCommentBox = ref(false)

// 修改 onMounted 部分
onMounted(() => {
  loadComments()
  createObserver()

  // 添加滚动监听
  const handleScroll = () => {
    const articleContent = document.querySelector('#article-content')
    if (articleContent) {
      const rect = articleContent.getBoundingClientRect()
      showCommentBox.value = rect.bottom <= window.innerHeight
    }
  }

  window.addEventListener('scroll', handleScroll)
  // 初始检查
  handleScroll()

  onUnmounted(() => {
    window.removeEventListener('scroll', handleScroll)
  })
})

// 清理观察器
onUnmounted(() => {
  if (observer) {
    observer.disconnect()
    observer = null
  }
})

// 处理头像加载失败
const handleAvatarError = (e: Event) => {
  const target = e.target as HTMLImageElement
  if (target) {
    target.src =
      ''
    target.classList.add('bg-gray-100')
  }
}

const isFocused = ref(false)

const authStore = useAuthStore()
</script>

<template>
  <div class="mt-8">
    <h2 class="text-xl font-bold mb-6 text-gray-800 flex items-center gap-2">
      <span>评论区</span>
      <span class="text-sm font-normal text-gray-500">({{ total }}条评论)</span>
    </h2>

    <!-- 评论列表 -->
    <div class="space-y-6">
      <div
        v-for="comment in comments"
        :key="comment.id"
        class="bg-white rounded-lg p-6 shadow-sm border border-gray-100 transition-all duration-300 hover:shadow-md"
      >
        <div class="flex items-start space-x-4">
          <img
            :src="comment.userAvatar"
            :alt="comment.userNickName"
            class="w-10 h-10 rounded-full object-cover border-2 border-gray-100 shadow-sm transition-transform hover:scale-110"
            @error="handleAvatarError"
          />
          <div class="flex-1 min-w-0">
            <div class="flex items-center justify-between mb-1">
              <span class="text-sm text-gray-600">
                {{ comment.userNickName }}
              </span>
              <span class="text-xs text-gray-500">{{ comment.createTime }}</span>
            </div>
            <p class="text-base text-gray-800 leading-relaxed mb-3 whitespace-pre-wrap">
              {{ comment.commentContent }}
            </p>

            <!-- 修改操作按钮区域 -->
            <div class="flex items-center justify-between text-sm mt-2">
              <button
                v-if="comment.replyCount > 0"
                @click="toggleExpand(comment.id)"
                class="text-gray-500 hover:text-gray-700 transition-colors flex items-center gap-1.5"
              >
                <span>{{ comment.replyCount }}条回复</span>
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  class="h-4 w-4 transition-transform duration-300"
                  :class="{ 'rotate-180': expandedComments.has(comment.id) }"
                  viewBox="0 0 20 20"
                  fill="currentColor"
                >
                  <path
                    fill-rule="evenodd"
                    d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
                    clip-rule="evenodd"
                  />
                </svg>
              </button>

              <button
                v-if="authStore.user"
                @click="() => handleReplyClick(comment.id)"
                class="text-gray-500 hover:text-gray-700 transition-colors"
              >
                {{ activeReplyId === comment.id ? '取消回复' : '回复' }}
              </button>
            </div>

            <!-- 回复组件 -->
            <div v-if="expandedComments.has(comment.id)" class="mt-4 transition-all duration-300">
              <CommentReply
                ref="replyComponents"
                :parent-id="comment.id"
                :article-id="props.articleId"
                :show-reply-input="activeReplyId === comment.id"
                @reply-submitted="handleReplySubmitted"
                @update:show-reply-input="(value) => handleReplyInputUpdate(comment.id, value)"
                @collapse="() => expandedComments.delete(comment.id)"
              />
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 固定在底部的评论输入框 -->
    <div
      v-if="authStore.user"
      class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-100 shadow-lg z-50"
      :class="{ 'translate-y-full': !showCommentBox }"
    >
      <div class="max-w-4xl mx-auto px-4">
        <div class="flex items-center gap-4 py-4">
          <img
            :src="authStore.user?.avatar"
            :alt="authStore.user?.nickName"
            class="w-11 h-11 rounded-full object-cover border-2 border-gray-100 flex-shrink-0"
            @error="handleAvatarError"
          />
          <div
            class="flex-1 relative flex items-center bg-gray-50 rounded-full hover:bg-gray-100 transition-colors group overflow-hidden"
            :class="{ 'bg-white ring-1 ring-gray-200': isFocused }"
          >
            <textarea
              v-model="commentContent"
              rows="1"
              class="flex-1 py-2.5 px-4 bg-transparent border-none outline-none resize-none text-sm placeholder:text-gray-400"
              placeholder="写下你的想法..."
              @keydown.enter.prevent="submitComment"
              @input="autoResize"
              @focus="isFocused = true"
              @blur="isFocused = false"
              ref="textareaRef"
            ></textarea>
            <div class="flex-shrink-0 p-1">
              <button
                @click="submitComment"
                class="h-10 w-16 bg-blue-600 hover:bg-blue-700 disabled:bg-gray-300 text-white rounded-full transition-colors flex items-center justify-center flex-shrink-0"
                :disabled="!commentContent.trim()"
              >
                <SendPlane class="w-6 h-6" />
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 加载触发器 -->
    <div
      ref="loadingTrigger"
      class="py-8 flex items-center justify-center"
      v-if="!isEnd"
      data-shown="false"
    >
      <div v-if="loading" class="flex items-center space-x-2 text-gray-600">
        <svg
          class="animate-spin h-5 w-5"
          xmlns="http://www.w3.org/2000/svg"
          fill="none"
          viewBox="0 0 24 24"
        >
          <circle
            class="opacity-25"
            cx="12"
            cy="12"
            r="10"
            stroke="currentColor"
            stroke-width="4"
          ></circle>
          <path
            class="opacity-75"
            fill="currentColor"
            d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
          ></path>
        </svg>
        <span class="text-sm">加载中</span>
        <span class="loading-dots"></span>
      </div>
      <div v-else class="text-gray-500 text-sm flex items-center gap-2">
        <span>继续下滑加载更多评论</span>
        <svg
          xmlns="http://www.w3.org/2000/svg"
          class="h-4 w-4 animate-bounce"
          fill="none"
          viewBox="0 0 24 24"
          stroke="currentColor"
        >
          <path
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="2"
            d="M19 14l-7 7m0 0l-7-7m7 7V3"
          />
        </svg>
      </div>
    </div>

    <!-- 到底提示 -->
    <div
      v-if="isEnd && comments.length > 0"
      class="text-center py-2 text-gray-400 text-sm border-t border-gray-100 mt-2 mb-20"
    >
      <span class="inline-flex items-center gap-2"> 已经到底啦 </span>
    </div>
  </div>
</template>

<style scoped>
@keyframes dotsAnimation {
  0% {
    content: '.';
  }
  33% {
    content: '..';
  }
  66% {
    content: '...';
  }
  100% {
    content: '';
  }
}

.loading-dots {
  display: inline-block;
  min-width: 1.5em;
}

.loading-dots::after {
  content: '';
  animation: dotsAnimation 1s infinite steps(4);
}

.animate-spin {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

/* 添加新的过渡效果 */
.transition-all {
  transition-property: all;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 300ms;
}

/* 添加hover效果 */
.hover\:shadow-md:hover {
  box-shadow:
    0 4px 6px -1px rgb(0 0 0 / 0.1),
    0 2px 4px -2px rgb(0 0 0 / 0.1);
}

/* 添加激活效果 */
.active\:scale-95:active {
  transform: scale(0.95);
}

/* 修改文本框样式 */
textarea {
  min-height: 36px;
  max-height: 80px;
  overflow-y: auto;
  line-height: 1.5;
}

/* 自定义滚动条样式 */
textarea::-webkit-scrollbar {
  width: 4px;
}

textarea::-webkit-scrollbar-track {
  background: transparent;
}

textarea::-webkit-scrollbar-thumb {
  background-color: #cbd5e1;
  border-radius: 2px;
}

/* 确保内容不会被固定评论框遮挡 */
.space-y-6 {
  padding-bottom: 0;
}

/* 修改固定定位的样式 */
.fixed {
  padding-bottom: env(safe-area-inset-bottom);
  transition: transform 0.3s ease-in-out;
  background-color: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(8px);
}

/* 添加新的动画效果 */
@keyframes slideUp {
  from {
    transform: translateY(100%);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

.fixed {
  animation: slideUp 0.3s ease-out;
}

/* 移除输入框的默认聚焦样式 */
textarea:focus {
  outline: none;
  box-shadow: none;
}

/* 输入框组样式 */
.group:focus-within {
  background-color: white;
  box-shadow: 0 0 0 1px rgb(229 231 235);
}
</style>
